﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Microsoft.Office.Interop.Word;

namespace PSTS.Models
{
    /// <summary>
    /// Class which provides functional to convert doc files into question models.   
    /// Implemented pattern: Singleton
    /// </summary>
    public class Converter
    {
        /// <summary>
        /// implementation of "singleton" pattern
        /// </summary>
        #region Singleton
        private static Converter _instance = null;

        /// <summary>
        /// Default constructor
        /// </summary>
        private Converter() { }

        /// <summary>
        /// The only instance for converter
        /// </summary>
        public static Converter Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new Converter();
                return _instance;
            }
        }
        #endregion //Singleton

        #region HelperMethods

        /// <summary>
        /// Get list of lines from file
        /// </summary>
        /// <param name="filename"> full path to file</param>
        /// <returns> List of strings containing each line in file</returns>
        //private List<string> FileToStrLines(string filename)
        //{
        //    Application word = new Application();
        //    Document doc = new Document();

        //    object fileName = filename;
        //    // Define an object to pass to the API for missing parameters
        //    object missing = System.Type.Missing;
        //    doc = word.Documents.Open(ref fileName,
        //            ref missing, ref missing, ref missing, ref missing,
        //            ref missing, ref missing, ref missing, ref missing,
        //            ref missing, ref missing, ref missing, ref missing,
        //            ref missing, ref missing, ref missing);

        //    String read = string.Empty;
        //    List<string> data = new List<string>();
        //    for (int i = 0; i < doc.Paragraphs.Count; i++)
        //    {
        //        string temp = doc.Paragraphs[i + 1].Range.Text.Trim();
        //        if (temp != string.Empty)
        //            data.Add(temp);
        //    }
        //    ((_Document)doc).Close();
        //    ((_Application)word).Quit();

        //    return data;
        //}

        #endregion //HelperMethods

        #region MainFunctional

        /// <summary>
        /// Add topics from specified file to specified chapter in database 
        /// </summary>
        /// <param name="chapterName"> Name of selected chapter</param>
        /// <param name="filePath"> full path to file </param>
        public void AddTopicsToChapter(string chapterName, string filePath)
        {
            Chapter ch = Repository.Instance.GetChapter(chapterName);
            this.AddTopicsToChapter(ch.Id, filePath);
        }

        /// <summary>
        /// Add topics from specified file to specified chapter in database 
        /// </summary>
        /// <param name="chapterId"> Id of selected chapter in database</param>
        /// <param name="filePath"> full path to file </param>
        public void AddTopicsToChapter(int chapterId, string filePath)
        {
            Repository db = Repository.Instance;
            //List<string> lines = this.FileToStrLines(filePath);
            Topic curTopic = null;
            Question curQuestion = null;

            Application word = new Application();
            Document doc = new Document();
            object filename = filePath;

            // Define an object to pass to the API for missing parameters
            object missing = System.Type.Missing;
            doc = word.Documents.Open(ref filename,
                    ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing, ref missing,
                    ref missing, ref missing, ref missing);

            String read = string.Empty;
            char[] sep = { '\v', '\n' };
            for (int i = 0; i < doc.Paragraphs.Count; i++)
            {
                string temp = doc.Paragraphs[i + 1].Range.Text.Trim();
                if (temp != string.Empty)
                {
                    string[] smallLines = temp.Split(sep, StringSplitOptions.RemoveEmptyEntries);
                    foreach (string line in smallLines)
                    {
                        //skip empty lines
                        if (line.Count() == 0)
                            continue;
                        //get a topic name
                        if (line[0] == '!')
                        {
                            curTopic = new Topic() { ChapterId = chapterId, Name = line.Substring(1), Id = -1 };
                            if (curQuestion != null && !db.HasQuestion(curQuestion))
                                db.AddQuestion(curQuestion);
                        }
                        else if (line[0] == '№')
                        {
                            if (curTopic.Id == -1)
                            {
                                if (!db.HasTopic(curTopic.Name, curTopic.ChapterId))
                                    db.AddTopic(curTopic.Name, curTopic.ChapterId);
                                curTopic = db.GetTopic(curTopic.Name);
                            }
                            else
                            {
                                if(!db.HasQuestion(curQuestion))
                                    db.AddQuestion(curQuestion);
                            }
                            curQuestion = new Question() { TopicId = curTopic.Id, Text = string.Empty, Id = -1, Answers = null, CorrectAnsIndex = -1 };
                        }
                        else if (line[0] == '+' || line[0] == '-')
                        {
                            if (curQuestion.Answers == null)
                                curQuestion.Answers = new List<string>();
                            curQuestion.Answers.Add(line.Substring(1));
                            if (line[0] == '+')
                                curQuestion.CorrectAnsIndex = curQuestion.Answers.Count() - 1;
                        }
                        else //just line of text
                        {
                            if (curTopic == null)//just text
                            {
                                //ignore
                            }
                            else if (curTopic.Id == -1)
                            {
                                curTopic.Name += line;
                            }
                            else if (curQuestion.Answers == null)
                            {
                                curQuestion.Text += line;
                            }
                            else
                            {
                                curQuestion.Answers[curQuestion.Answers.Count - 1] += line;
                            }
                        }
                    }
                }
            }
            ((_Document)doc).Close();
            ((_Application)word).Quit();

            if (curQuestion != null && !db.HasQuestion(curQuestion))
            {
                db.AddQuestion(curQuestion);
            }
        }
    }

        #endregion //MainFunctional
}
